package com.base.server.modules.sys.controller;

import com.alibaba.fastjson.JSON;
import com.base.server.common.config.RedisClient;
import com.base.server.common.config.jwt.JwtUtil;
import com.base.server.common.constant.Constant;
import com.base.server.common.response.CommonResponse;
import com.base.server.common.utils.MD5Utils;
import com.base.server.modules.sys.entity.LoginVo;
import com.base.server.modules.sys.service.SysService;
import com.base.server.modules.user.controller.UserInfoController;
import com.base.server.modules.user.entity.UserInfoVo;
import com.google.common.collect.Maps;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * 描述：系统前端控制器
 * <p>
 * 作者：Ostrich Hu
 * 时间：2019/12/16 15:26 星期一
 */
@RestController
@RequestMapping("api/rest/sys")
public class SysController {

    private final Logger logger = LoggerFactory.getLogger(UserInfoController.class);

    @Autowired
    public SysService sysService;

    @Autowired
    public SessionDAO sessionDAO;

    @Autowired
    private RedisClient redis;

    @ApiOperation("验证是否记住我")
    @GetMapping(value = "/")
    public CommonResponse isRememberMe() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isRemembered()) {
            return CommonResponse.ok(subject.getPrincipal());
        } else {
            return CommonResponse.ok();
        }
    }

    @ApiOperation("登录")
    @GetMapping(value = "/login")
    public ResponseEntity<CommonResponse> login(LoginVo vo) {
//        Subject subject = SecurityUtils.getSubject();
//        UsernamePasswordToken token = new UsernamePasswordToken(vo.getLoginName(), MD5Utils.encrypt(vo.getPassword()));
//        token.setRememberMe(vo.isRememberMe());
//        UserInfoVo principal = (UserInfoVo) SecurityUtils.getSecurityManager()
//                .login(subject, token)
//                .getPrincipal();
        String account = vo.getLoginName();
        String password = vo.getPassword();
        UserInfoVo user = sysService.loginByName(account);
        if (account == null || password == null || user == null) {
            return ResponseEntity.ok(CommonResponse.error("账号或者密码为空"));
        }
        if (!MD5Utils.encrypt(password).equals(user.getPassword())) {
            return ResponseEntity.ok(CommonResponse.error(Constant.Permission.PWD_ERR, "密码错误"));
        }
        String redisCacheKey = Constant.RedisConstant.PREFIX_TOKEN_U_CACHE + account;
        String redisRefreshKey = Constant.RedisConstant.PREFIX_TOKEN_REFRESH_TIME + account;
        String currentTimeMillis = String.valueOf(System.currentTimeMillis());

        // 清除可能存在的shiro权限信息缓存
        if (redis.hasKey(redisCacheKey)) {
            redis.del(redisCacheKey);
        }
        redis.set(redisCacheKey, JSON.toJSONString(user), 28800);
        redis.set(redisRefreshKey, currentTimeMillis, 28800);

        String token = JwtUtil.sign(account, currentTimeMillis);
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.AUTHORIZATION, token);
        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.AUTHORIZATION);
        return new ResponseEntity<>(CommonResponse.ok(user), headers, HttpStatus.OK);
    }

    @ApiOperation("登出")
    @GetMapping(value = "/logout/{account}")
    public CommonResponse logout(@PathVariable String account) {
//        SecurityUtils.getSubject().logout();
//        redis.del(Constant.RedisConstant.PREFIX_TOKEN_U_CACHE + account);
//        redis.del(Constant.RedisConstant.PREFIX_TOKEN_REFRESH_TIME + account);
        return CommonResponse.ok("登出成功");
    }

    @ApiOperation(value = "验证token", notes = "验证token是否有效")
    @PostMapping(value = "/validToken/{token}")
    public CommonResponse validToken(@PathVariable String token) {
        boolean verify = JwtUtil.verify(token);
        if (verify) {
            String claim = JwtUtil.getClaim(token, Constant.JWT.ACCOUNT);
            Map<String, Object> map = Maps.newHashMap();
            map.put("code", Constant.Permission.SUCCESS);
            map.put("data", claim);
            map.put("msg", "token 有效");
            return CommonResponse.ok(map);
        } else {
            return CommonResponse.error(Constant.Permission.UN_LOGIN, "token 失效");
        }
    }
}
